package edu.up.firesawakening;

import java.io.Serializable;

/**
 * Represents a single tile of the game board.
 * 
 * @author Alex Hanemann
 * @author Viet Phan
 * @version 7 November 2012
 */
public class Tile implements Serializable, Cloneable, Comparable<Tile> {

	/**
	 * Serial ID
	 */
	private static final long serialVersionUID = -1303575747197020623L;

	/**
	 * For use by TacticsGame to keep track of costs
	 */
	public int currCost;

	/**
	 * Types of tiles
	 */
	public static enum TileType {
		PLAINS, RIVER, MOUNTAIN
	};

	/**
	 * Unit occupying this tile
	 */
	protected Unit m_unit = null;

	/**
	 * Type of the tile (River, Plains, etc). May be used later for beautiful
	 * GUI, tile-specific bonuses, etc.
	 */
	protected TileType m_type;

	/**
	 * Cost to move through the tile. Set during game creation.
	 */
	protected int m_moveCost;

	/**
	 * x coordiate of this tile
	 */
	protected int m_x;

	/**
	 * y coordiate of this tile
	 */
	protected int m_y;

	/**
	 * @return the cost of moving through this tile
	 */
	public int getMoveCost() {
		return m_moveCost;
	}

	/**
	 * @return the type of this tile
	 */
	public TileType getType() {
		return m_type;
	}

	/**
	 * @return this tile's x coordinate
	 */
	public int getX() {
		return m_x;
	}

	/**
	 * @return this tile's y coordinate
	 */
	public int getY() {
		return m_y;
	}

	/**
	 * @param unit
	 *            the unit to place on this tile
	 * @return false if tile already occupied, true otherwise
	 */
	public boolean setUnit(Unit unit) {
		if (m_unit == null) {
			m_unit = unit;
			return true;
		}

		return false;
	}

	/**
	 * @return the unit occupying this tile
	 */
	public Unit getUnit() {
		return m_unit;
	}

	/**
	 * Wipes the unit out of the tile. Don't do this until you've already set
	 * the unit down somewhere else!
	 */
	public void removeUnit() {
		m_unit = null;
	}

	/**
	 * @return Whether or not this tile has a unit
	 */
	public boolean isOccupied() {
		return m_unit != null;
	}

	/**
	 * Constructs a tile object with the specified type and location.
	 * 
	 * @param type
	 * @param xCoordIn
	 * @param yCoordIn
	 */
	public Tile(TileType type, int xCoordIn, int yCoordIn) {
		m_type = type;
		m_x = xCoordIn;
		m_y = yCoordIn;

		switch (m_type) {
		case PLAINS:
			m_moveCost = 1;
			break;
		case MOUNTAIN:
			m_moveCost = 999;
			break;
		case RIVER:
			m_moveCost = 2;
			break;
		default:
			m_moveCost = 1;
		}
	}

	@Override
	public Tile clone() {
		Tile t = new Tile(m_type, m_x, m_y);

		if (m_unit != null) {
			t.setUnit(m_unit.clone());
		}

		return t;
	}

	public int compareTo(Tile other) {
		return currCost - other.currCost;
	}
}
